package com.example.skillcinema.db.repositories

import com.example.skillcinema.db.apis.RetrofitService
import com.example.skillcinema.db.displaymodels.FilmDisplayModel
import com.example.skillcinema.db.enums.FilmCollections
import com.example.skillcinema.db.enums.FilmTypes
import com.example.skillcinema.db.enums.GalleryImageTypes
import com.example.skillcinema.db.localdb.ApplicationDataBase
import com.example.skillcinema.db.models.Film
import com.example.skillcinema.db.models.Season
import com.example.skillcinema.db.models.Staff
import com.example.skillcinema.db.responses.FiltersCountriesResponse
import com.example.skillcinema.db.responses.FiltersGenresResponse
import com.example.skillcinema.db.responses.ImageItemResponse
import com.example.skillcinema.db.responses.SeasonResponse
import com.example.skillcinema.extensions.sliceForPreview
import com.example.skillcinema.extensions.sliceToPages
import kotlinx.coroutines.Delay
import kotlinx.coroutines.delay
import retrofit2.Retrofit
import java.time.Month
import javax.inject.Inject
import javax.inject.Singleton
import kotlin.collections.map
import kotlin.random.Random
@Singleton
class FilmForPreviewRepository @Inject constructor(db: ApplicationDataBase) : BaseRepository(db) {
    suspend fun getPremiersForPreview(year: Int, month: Month): List<FilmDisplayModel> =
        RetrofitService.premierApi.getAll(year, month).items.sliceToPages(1).map { premierItem ->
            getFilmById(
                premierItem.kinopoiskId
            )
        }

    suspend fun getTopForPreview(
        type: FilmCollections = FilmCollections.TOP_POPULAR_ALL, page: Int
    ): List<FilmDisplayModel> =
        RetrofitService.filmsApi.getTopPopular(type, page).items.sliceForPreview().map { filmItem ->
            getFilmById(filmItem.kinopoiskId)
        }

    suspend fun getRandomFilters(): Pair<FiltersCountriesResponse, FiltersGenresResponse> {
        val fetchedData = RetrofitService.filmsApi.getFilters()
        return Pair(
            fetchedData.countries[Random.nextInt(1, 10)],
            fetchedData.genres[Random.nextInt(1, 10)]
        )
    }

    suspend fun getRandomFilteredFilms(
        country: Int,
        genre: Int,
        page: Int
    ): List<FilmDisplayModel> {
        delay(250)
        return try {
            RetrofitService.filmsApi.getAll(country, genre, page = page).items.sliceForPreview()
                .map { filmItem ->
                    getFilmById(filmItem.kinopoiskId)
                }
        } catch (e: Exception) {
            throw e
        }
    }

    suspend fun getSerialsForPreview(page: Int): List<FilmDisplayModel> =
        RetrofitService.filmsApi.getSerials(FilmTypes.TV_SERIES, page).items.sliceForPreview()
            .map { serialItem ->
                getFilmById(serialItem.kinopoiskId)
            }

    suspend fun getFilmDetails(id: Int): Film = RetrofitService.filmsApi.getById(id)

    suspend fun getSeasonsForPreview(id: Int): List<Season> =
        RetrofitService.filmsApi.getSeasons(id).items

    suspend fun getActors(id: Int): List<Staff> =
        try {
            RetrofitService.filmsApi.getStaff(id).filter { it.professionKey == "ACTOR" }
        } catch (e: retrofit2.HttpException) {
            listOf()
        }

    suspend fun getStaff(id: Int): List<Staff> =
        try {
            RetrofitService.filmsApi.getStaff(id).filter { it.professionKey != "ACTOR" }
        } catch (e: retrofit2.HttpException) {
            listOf()
        }

    suspend fun getGallery(
        id: Int,
        page: Int = FIRST_PAGE,
        galleryType: GalleryImageTypes = GalleryImageTypes.STILL
    ): Pair<Int, List<ImageItemResponse>> =
        getGalleryImageCount(id)

    suspend fun getGalleryImageCount(id: Int): Pair<Int, List<ImageItemResponse>> {
        var resultCount = 0
        var list: List<ImageItemResponse> = listOf()
        var resultList: List<ImageItemResponse> = listOf()
        for (imageType in GalleryImageTypes.entries) {
            list = RetrofitService.filmsApi.getGallery(
                id,
                page = FIRST_PAGE,
                imageType
            ).items
            if (list.count() > 0 && resultList.count() == 0) {
                resultList = list
            }
            resultCount += list.count()
        }
        return resultCount to resultList
    }

    suspend fun getSimilar(id: Int): List<FilmDisplayModel> =
        RetrofitService.filmsApi.getSimilar(id).items.sliceForPreview().map { related ->
            getFilmById(related.filmId)
        }
}